package com.qingcloud.base.exception;

import cn.hutool.core.exceptions.ExceptionUtil;
import com.qingcloud.base.pojo.ApiResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

/**
 * 异常统一处理
 *
 * @author wangjinnan
 */
@ControllerAdvice
@ResponseBody
public class ExceptionHandlerAdvice {

    private static final Logger logger = LoggerFactory.getLogger(ExceptionHandlerAdvice.class);

    /**
     * 拦截业务异常
     */
    @ExceptionHandler(WamingException.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public ApiResult handleWamingException(WamingException e) {
        logger.error("业务运行异常:", e);
        String trace = ExceptionUtil.stacktraceToString(e);
        return ApiResult.fail(e.getCode(), e.getMessage(), trace);
    }

    /**
     * 参数错误异常
     */
    @ExceptionHandler(IllegalArgumentException.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public ApiResult handleIllegalArgumentException(IllegalArgumentException e) {
        logger.error("请求参数异常:", e);
        return ApiResult.fail(e.getMessage());
    }

    /**
     * 参数校验异常
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public ApiResult handleIllegalArgumentException(MethodArgumentNotValidException e) {
        logger.error("请求参数异常:", e);
        return ApiResult.fail(e.getBindingResult().getFieldError().getDefaultMessage());
    }

    /**
     * 其他类型异常
     */
    @ExceptionHandler({Throwable.class})
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public ApiResult handleOther(Throwable e) {
        logger.error("服务器异常:", e);
        String trace = ExceptionUtil.stacktraceToString(e);
        return ApiResult.fail(e.getMessage(), trace);
    }

}